home *** CD-ROM | disk | FTP | other *** search
/ PC-SIG Library 8 / PC-SIG Library CD-ROM (8th Edition) (1990-04).iso / 201_300 / disk0299 / red.asm < prev    next >
Encoding:
Assembly Source File  |  1985-01-21  |  9.5 KB  |  254 lines

  1. RED segment para public 'code'
  2.     assume cs:red, ds:red, es:red, ss:nothing
  3.     org 100h        ;.com format
  4. begin:    
  5.     jmp    code_start    ; jump around data declarations
  6. declare:    ; messages, storage areas, equates
  7.     copyright    db    'REDirect (C) 1985, Dickinson Associates Inc.'
  8.             db    13,10,'$'
  9.     path_file_len    equ    77  ;length=1, path=63, filename=12, 0=1
  10.     source_file    db    path_file_len dup (0)
  11.     target_path    db    path_file_len dup (0)
  12.     source_end    dw    0
  13.     target_end    dw    0
  14.     pc_dos_ver    db    0
  15.     valid_in    db    'abcdefghijklmnopqrstuvwxyz,;=',9
  16.     valid_out    db    'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 DUP(32)
  17.     valid_num    equ    $ - valid_out + 1
  18.     err_flag    db    0
  19.     err_head    db    10,13,'REDirect Error - $'
  20.     bad_version    db    'Incorrect PC-DOS Version$'
  21.     no_parms    db    'Correct Syntax is:',13,10,10
  22.     db    'RED [d:][source_path]source_filename[.ext] [d:][target_path]$'
  23.     file_not_found    db    'File not Found$'
  24.     path_not_found    db    'Target Path not Found$'
  25.     pc_dos_2_patch    db    13,10,'or $'
  26.     drives_conflict    db    'Source and Target Disk Drives Conflict$'
  27.     undefined_err    db    'Undefined Error: PC-DOS Function 56H$'
  28.     err_tail    db    10,10,13,' . . . Aborting',10,13,13,'$'
  29.     good_msg    db    ' . . REDirected to . . $'
  30.     bad_msg1    db    ' . . Not REDirected . . $'
  31.     bad_msg2    db    ' . . already exists$'
  32.     end_line    db    10,13,'$'
  33. code_start:    ;parse command line into source and target parameters
  34.     mov    dx,offset copyright    ;display copyright notice
  35.     mov    ah,9h
  36.     int    21h
  37.     mov    ah,30h            ; get pc-dos version
  38.     int    21h
  39.     mov    pc_dos_ver,al
  40.     mov    si,80h            ;psp parameter byte count pointer
  41.     mov    cl,[si]            ;move byte count to cl
  42.     xor    ch,ch            ;zero ch
  43.     jcxz    no_parms_passed        ;if cx is zero, there are no parameters
  44.     mov    dx,cx            ;save byte count in dx
  45.     inc    si            ;point to parameter area
  46.     mov    di,si            ;copy si to di for cleanup routine
  47.     cld                ;set direction flag to forward
  48. clean_parms:    ;change valid delimiters to blanks, lower to upper case
  49.     lodsb                ;load each character to al
  50.     push    di            ;save di on stack
  51.     mov    di,offset valid_in    ;point to table of valid inputs
  52.     push    cx            ;save cx on stack
  53.     mov    cx,valid_num        ;set CX TO NUMBER OF INPUTS TO LOOK FOR
  54. repne    scasb                ;see if any are in al
  55.     jcxz    clean_end        ;if not, change nothing
  56.     mov    bx,valid_num        ;set up bx to point to valid output
  57.     sub    bx,cx            ;this will leave bx one off
  58.     mov    al,valid_out [bx-1]    ;load the valid output to al
  59. clean_end:
  60.     pop    cx            ;restore cx
  61.     pop    di            ;restore di
  62.     stosb                ;store modified al back to psp
  63. loop    clean_parms            ;loop until cx is zero
  64.     mov    cx,dx            ;restore number of bytes in psp to cx
  65.     mov    dx,2            ;set dx to look for up to 2 parameters
  66.     mov    bx,offset source_file    ;set bx to address of 1st parameter
  67.     mov    al,' '            ;set up to scan for first non-blank
  68.     mov    di,81h            ;set di to pc-dos parameter pointer
  69. find_parms:    ;start looking for parameters, load to program storage
  70. repe    scasb                ;scan while blanks
  71.     mov    si,di            ;set si to second non-blank byte
  72.     dec    si            ;adjust it to first non-blank byte
  73.     inc    cx            ;adjust cx to compensate
  74.     jcxz    parms_loaded        ;if cx is zero, no parameters left
  75.     mov    di,bx            ;set di to parameter hold area
  76.     mov    ax,cx            ;store cx to first byte of hold area
  77.     stosb                ;di is adjusted to second byte here
  78. store:    lodsb                ;load each byte to al
  79.     cmp    al,' '            ;is it a blank?
  80.     jz    end_store        ;yes, end of this parameter
  81.     stosb                ;no, store the byte to hold area
  82. end_store:    
  83.     loopnz    store            ;keep looking
  84.     sub    [bx],cx            ;store number of bytes in each
  85.     jcxz    parms_loaded        ;if cx is zero, no more parameters
  86.     dec    byte ptr    [bx]    ;parameter to first byte of hold area
  87.     mov    di,si            ;set up to scan for next non-blank
  88.     dec    di            ;adjust di to point to the blank
  89.     inc    cx            ;adjust cx to compensate
  90.     dec    dx            ;decrement dx counter
  91.     cmp    dx,0            ;is dx zero?
  92.     jz    parms_loaded        ;yes all expected parameters loaded
  93.     add    bx,path_file_len    ;no, point to next part of hold area
  94.     jmp    find_parms        ;go back and look for more
  95. parms_loaded:                ;all parameters are loaded
  96.     cmp    source_file[0],0    ;if there are no bytes in the
  97.     ja    fix_up            ;source_file, no paramters present
  98. no_parms_passed:            ;exit with an error if there are
  99.     mov    dx,offset no_parms    ;no parameters passed
  100.     jmp    error_exit
  101. fix_up:                    ;fix source_file and target_path
  102.     mov    si,offset source_file    ;for search and rename calls
  103.     lodsb                ;get number of bytes
  104.     xor    ah,ah            ;zero    ah
  105.     mov    di,si            ;mov si to di for scan
  106.     add    di,ax            ;start scan at end of parameter
  107.     dec    di            ;
  108.     mov    cx,ax            ;set cx to number of bytes
  109.     mov    al,'\'            ;scan for the last '\'
  110.     std                ;set direction flag to reverse
  111. repnz    scasb                ;scan while not '\'
  112.     jnz    no_source_dir        ;if zero flag not set, '\' not found
  113.     add    di,2            ;add 2 to di to point to file name
  114.     jmp    source_fixed        ;position
  115. no_source_dir:                ;no source directory was specified
  116.     add    di,1            ;adjust di
  117.     cmp    source_file[2],':'    ;check for specified disk drive
  118.     jne    source_fixed        ;none present, we're done
  119.     mov    di,offset source_file[3];yes, set di to point of first byte
  120. source_fixed:                ;after ':'
  121.     mov    source_end,di        ;move di to source_end pointer
  122.     cld                ;set direction flag to forward
  123.     mov    si,offset target_path    ;set up to look for '\' present
  124.     lodsb                ;get number of bytes
  125.     cmp    al,0            ;if it's zero, no target specified
  126.     je    no_target
  127.     xor    ah,ah            ;zero ah
  128.     add    si,ax            ;add it to si to point to end
  129.     dec    si            ;decrement si to adjust
  130.     lodsb                ;look at last byte
  131.     mov    di,si            ;copy si to di
  132.     cmp    al,'\'            ;is last byte a '\'?
  133.     je    target_fixed        ;yes, everything's fine
  134.     cmp    target_path[0],2    ;if target_path is 2 bytes long and
  135.     jne    store_slash        ;is a drive specification,
  136.     cmp    target_path[2],':'    ;let it default to the current
  137.     je    target_fixed        ;directory
  138. store_slash:                ;place a '\' at the end of
  139.     mov    al,'\'            ;target_path if user did not
  140.     stosb
  141. target_fixed:
  142.     mov    target_end,di        ;move di to target_end pointer
  143.     jmp    find_file
  144. no_target:                ;set up to allow target path default
  145.     mov    target_end,offset target_path + 1    ;to current path
  146. find_file:
  147.     mov    dx,offset source_file + 1    ;dx points to source file
  148.     mov    ah,4Eh            ;request function 4Eh (find first file)
  149.     mov    cx,0            ;set cx to zero for normal files only
  150.     int    21h            ;call pc-dos
  151.     jnc    found_file        ;if no error, first file found
  152.     mov    dx,offset file_not_found    ;if no files found, exit
  153.     jmp    error_exit            ;program with error message
  154. found_file:
  155.     mov    di,source_end        ;di points to end of source path
  156.     mov    si,9Eh            ;si points to default DTA in psp
  157.     mov    cx,13            ;dta will have 13 bytes
  158. rep    movsb                ;move bytes to source_file
  159.     mov    di,target_end        ;di points to end of target path
  160.     mov    si,9Eh            ;si points to default DTA in psp
  161.     mov    cx,13            ;DTA will have 13 bytes
  162. rep    movsb                ;move bytes to target_path
  163.     mov    dx,offset source_file + 1    ;dx points to old file name
  164.     mov    di,offset target_path + 1    ;di points to new file name
  165.     mov    ah,56h            ;request function 56h (rename file)
  166.     int    21h            ;call pc-dos
  167.     jnc    good_red        ;if no error, call was successful
  168.     cmp    ax,3            ;check for error 3 (path not found)
  169.     jne    err_5
  170.     mov    dx,offset path_not_found
  171.     jmp    error_exit        ;exit program with error message
  172. err_5:    cmp    ax,5            ;check    for error 5 (file inaccessible)
  173.     jne    err_17
  174.     mov    err_flag,1        ;soft error -
  175.     call    red_msg            ;issue message with subroutine
  176.     jmp    next_file        ;and keep going
  177. err_17:    cmp    ax,17            ;check for error 17 (drive conflict)
  178.     jne    undef
  179.     mov    dx,offset drives_conflict
  180.     jmp    error_exit        ;exit program with error message
  181. undef:    mov    dx,offset undefined_err    ;undefined error from function 56h
  182.     jmp    error_exit        ;exit program with error message
  183. good_red:                
  184.     mov    err_flag,0        ;set error flag off and
  185.     call    red_msg            ;issure message with subroutine
  186. next_file:                ;look for next file
  187.     mov    ah,4Fh            ;request function 4fh (find next file)
  188.     mov    cx,0
  189.     int    21h
  190.     jnc    found_another        ;no error, another file was found
  191.     jmp    end_ok            ;error, we're done finding files
  192. found_another:
  193.     jmp    found_file        ;go process next file
  194. end_ok:    int    20h            ;exit to pc-dos
  195.  
  196. error_exit:                ;print error message and exit
  197.     push    dx            ;save error message pointer on stack
  198.     mov    ah,9
  199.     mov    dx,offset err_head
  200.     int    21h
  201.     mov    ah,9
  202.     pop    dx
  203.     int    21h
  204.     mov    ah,9
  205.     mov    dx,offset err_tail
  206.     int    21h
  207.     int    20h            ;exit to pc-dos
  208.  
  209. red_msg    proc    near    ;display message for each file
  210.     mov    cx,2            ;2 fields - source & target file
  211.     mov    bx,offset source_file + 1    ;point to source file
  212. start1:    mov    si,bx            ;copy bx to si
  213. start2:    lodsb                ;load each byte to al
  214.     cmp    al,0            ;if ascii 0 end of field
  215.     je    between
  216.     mov    dl,al            ;copy byte to dl for funtion 2h
  217.     mov    ah,2h            ;request function 2h
  218.     int    21h            ;call pc-dos
  219.     jmp    start2            ;get next character
  220. between:cmp    cx,2            ;is it first or second field
  221.     jne    cr_lf            ;if second, display end of message
  222.     cmp    err_flag,0        ;is this a success message?
  223.     jz    ok1            ;yes, go to good_msg
  224.     mov    dx, offset bad_msg1    ;no, display first part of bad_msg
  225.     mov    ah,9h            ;request function 9h
  226.     int    21h            ;call pc-dos
  227.     jmp    next            ;go process next field
  228. ok1:    mov    dx, offset good_msg    ;display good_msg
  229.     mov    ah,9h            ;request function 9h
  230.     int    21h            ;call pc-dos
  231.     jmp    next            ;go process next field
  232. cr_lf:    cmp    err_flag,0        ;is this a success message?
  233.     jz    ok2            ;yes, go to terminate message
  234.     mov    dx,offset bad_msg2    ;no, display second part of bad_msg
  235.     mov    ah,9h            ;request function 9h
  236.     int    21h            ;call pc-dos
  237. pc_dos_2:                ;patch for incorrect error
  238.     cmp    pc_dos_ver,3        ;return in pc_dos 2.0 and 2.1
  239.     jae    ok2
  240.     mov    dx,offset pc_dos_2_patch
  241.     mov    ah,9h
  242.     int    21h
  243.     mov    dx,offset path_not_found
  244.     int    21h
  245. ok2:    mov    dx,offset end_line    ;terminate display line
  246.     mov    ah,9h            ;request function 9h
  247.     int    21h
  248. next:    add    bx,path_file_len        ;move bx to point to next field
  249.     loop    start1            ;loop for second field
  250.     ret                ;or end and return to calling point
  251. red_msg        endp
  252. red    ends
  253.     end    begin
  254.